<script lang="ts">

import { defineComponent, getCurrentInstance, onMounted, ref } from "vue";

import * as THREE from 'three'
import { BufferGeometryUtils } from 'three/examples/jsm/utils/BufferGeometryUtils.js'

export default defineComponent({
  setup(){
    const { proxy }  = getCurrentInstance()
    const session5 = ref<HTMLElement | null>(null);
    const StartTime = Date.now()
    let camera: { position: { x: number; z: number } },
      scene: { background: any; add: (arg0: any) => void },
      renderer: {
        setSize: (arg0: number, arg1: number) => void
        domElement: any
        render: (arg0: any, arg1: any) => void
      },
      mesh

    // 云的个数
    const CloudCount = 1000
    // 每个云所占z轴的长度
    const perCloudZ = 15
    // 所有的云一共的Z轴长度
    const cameraPositionZ = CloudCount * perCloudZ
    // X轴和Y轴平移的随机参数
    const RandomPositionX = 80
    const RandomPositionY = 120
    // 背景色，目前为天蓝色
    const BackGroundColor = '#1e4877'

    const pageWidth = document.getElementById('app')!.clientWidth
    const pageHeight = 936
    function init() {
      // 透视相机，只有距离相机1~500的物体才可以被渲染
      camera = new THREE.PerspectiveCamera(70, pageWidth / pageHeight, 1, 1000)
      // 相机的位置，平移下左右平衡
      camera.position.x = Math.floor(RandomPositionX / 2)
      // 最初在最远处
      camera.position.z = cameraPositionZ

      // 线性雾，就是说雾化效果是随着距离线性增大的
      // 可以改变雾的颜色，发现远处的云的颜色有所变化
      const fog = new THREE.Fog(BackGroundColor, 1, 1000)

      scene = new THREE.Scene()
      scene.background = new THREE.Color(BackGroundColor)

      const texture = new THREE.TextureLoader().load('@assets/login/cloud.png')

      // 一个平面形状
      const geometry = new THREE.PlaneGeometry(64, 64)

      const geometries: any[] = []

      const vShader = `
          varying vec2 vUv;
          void main()
          {
            vUv = uv;
            gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
          }
        `
      const fShader = `
          uniform sampler2D map;
          uniform vec3 fogColor;
          uniform float fogNear;
          uniform float fogFar;
          varying vec2 vUv;
          void main()
          {
            float depth = gl_FragCoord.z / gl_FragCoord.w;
            float fogFactor = smoothstep( fogNear, fogFar, depth );
            gl_FragColor = texture2D(map, vUv );
            gl_FragColor.w *= pow( gl_FragCoord.z, 20.0 );
            gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );
          }
        `
      // 贴图材质
      const material = new THREE.ShaderMaterial({
        // 这里的值是给着色器传递的
        uniforms: {
          map: {
            type: 't',
            value: texture
          },
          fogColor: {
            type: 'c',
            value: fog.color
          },
          fogNear: {
            type: 'f',
            value: fog.near
          },
          fogFar: {
            type: 'f',
            value: fog.far
          }
        },
        vertexShader: vShader,
        fragmentShader: fShader,
        transparent: true
      })

      for (var i = 0; i < CloudCount; i++) {
        const instanceGeometry = geometry.clone()

        // 把这个克隆出来的云，通过随机参数，做一些位移，达到一堆云彩的效果，每次渲染出来的云堆都不一样
        // X轴偏移后，通过调整相机位置达到平衡
        // Y轴想把云彩放在场景的偏下位置，所以都是负值
        // Z轴位移就是：当前第几个云*每个云所占的Z轴长度
        instanceGeometry.translate(
          Math.random() * RandomPositionX,
          -Math.random() * RandomPositionY,
          i * perCloudZ
        )
        geometries.push(instanceGeometry)
      }

      // 把这些形状合并
      const mergedGeometry = BufferGeometryUtils.mergeBufferGeometries(geometries)

      // 把上面合并出来的形状和材质，生成一个物体
      mesh = new THREE.Mesh(mergedGeometry, material)
      // 添加进场景
      scene.add(mesh)

      renderer = new THREE.WebGLRenderer({ antialias: false })
      renderer.setSize(pageWidth, pageHeight)

      session5.value!.appendChild(renderer.domElement)
    }

    function animate() {
      requestAnimationFrame(animate)

      // 从最远的z轴处开始往前一点一点的移动，达到穿越云层的目的
      camera.position.z = cameraPositionZ - (((Date.now() - StartTime) * 0.03) % cameraPositionZ)

      renderer.render(scene, camera)
    }

    const loginForm = ref({
      username: "admin",
      password: "admin123",
      rememberMe: false,
      code: "",
      uuid: ""
    });
    const loginRules = {
      username: [{ required: true, trigger: "blur", message: "请输入您的账号" }],
      password: [{ required: true, trigger: "blur", message: "请输入您的密码" }],
      code: [{ required: true, trigger: "change", message: "请输入验证码" }]
    };
    const codeUrl = ref("");
    const loading = ref(false);
// 验证码开关
    const captchaEnabled = ref(false);

    function handleLogin() {
      loading.value = true;
      console.log(loginForm.value)
      proxy.$refs.loginRef.validate((valid:boolean) => {
        if (valid) {
          console.log(valid)
          loading.value = false;
          // const { username, password, rememberMe, code, uuid } = loginForm.value;
          // const res = await login({ username, password, rememberMe, code, uuid });
          // if (res.code === 200) {
          //   proxy.$router.push("/");
          // } else {
          //   proxy.$message.error(res.msg);
          // }
        } else {
          return false;
        }
    })

      // if (loginForm.value.username !== "" && loginForm.value.password !== "") {
      //   proxy.$router.push({ path: '/index' || "/" });
      //
      // } else {
      //   proxy.$message.error("请输入账号和密码");
      // }
      loading.value = false;
    }
    onMounted(() => {
      init()
      animate()
    })
    return { session5,loginForm,loginRules,handleLogin,captchaEnabled,loading,codeUrl }
  }
})
</script>

<template>
  <div class="bg_box login" ref="session5">
    <el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="login-form">
      <h3 class="title">数据可视化系统</h3>
      <el-form-item prop="username">
        <el-input
          v-model="loginForm.username"
          type="text"
          size="large"
          auto-complete="off"
          placeholder="账号"
        >
          <template #prefix><svg-icon icon-class="user" class="el-input__icon input-icon" /></template>
        </el-input>
      </el-form-item>
      <el-form-item prop="password">
        <el-input
          v-model="loginForm.password"
          type="password"
          size="large"
          auto-complete="off"
          placeholder="密码"
          @keyup.enter="handleLogin"
        >
          <template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template>
        </el-input>
      </el-form-item>
      <el-form-item prop="code" v-if="captchaEnabled">
        <el-input
          v-model="loginForm.code"
          size="large"
          auto-complete="off"
          placeholder="验证码"
          style="width: 63%"
          @keyup.enter="handleLogin"
        >
          <template #prefix><svg-icon icon-class="validCode" class="el-input__icon input-icon" /></template>
        </el-input>
      </el-form-item>
      <!--      <el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">记住密码</el-checkbox>-->
      <el-form-item style="width:100%;">
        <el-button
          :loading="loading"
          size="large"
          type="primary"
          style="width:100%;"
          @click.prevent="handleLogin"
        >
          <span v-if="!loading">登 录</span>
          <span v-else>登 录 中...</span>
        </el-button>
      </el-form-item>
    </el-form>
    <!--  底部  -->
    <div class="el-login-footer">
      <span>Copyright © 2018-2024 瑞霖信达 All Rights Reserved.</span>
    </div>
  </div>
</template>

<style lang='scss' scoped>

.login {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100vh;
  //background-image: url("../assets/images/login-background.jpg");
  //background-size: cover;
}
.title {
  margin: 0px auto 30px auto;
  text-align: center;
  color: #707070;
}

.login-form {
  position: absolute;
  border-radius: 6px;
  background: #ffffff;
  opacity: 0.9;
  width: 400px;
  padding: 25px 25px 5px 25px;
  .el-input {
    height: 40px;
    input {
      height: 40px;
    }
  }
  .input-icon {
    height: 39px;
    width: 14px;
    margin-left: 0px;
  }
}
.login-tip {
  font-size: 13px;
  text-align: center;
  color: #bfbfbf;
}
.login-code {
  width: 33%;
  height: 40px;
  float: right;
  img {
    cursor: pointer;
    vertical-align: middle;
  }
}
.el-login-footer {
  height: 40px;
  line-height: 40px;
  position: fixed;
  bottom: 0;
  width: 100%;
  text-align: center;
  color: #000;
  font-family: Arial;
  font-size: 12px;
  letter-spacing: 1px;
}
.login-code-img {
  height: 40px;
  padding-left: 12px;
}
</style>
